﻿module Sustainalytics.Events {
    import Common = Sustainalytics.Common;
    export class EventAddEditController {

        // controller scope
        public $scope: ng.IScope;
        // services
        private $q: ng.IQService;
        private $location: ng.ILocationService;
        private $routeParams: ng.route.IRouteParamsService;
        private notificationFactory: INotificationFactory;
        private backendService: EventsService;
        private staticObjects: IStaticObjects;
        private asyncSaveOperation: Sustainalytics.Common.AsyncHttpOperation<any>;
        private asyncLoadOperation: Sustainalytics.Common.AsyncHttpOperation<any>;
        private eventsStatusesService: EventsStatusesService;

        // specifies whether current controller is in loading state
        public isLoading: boolean;
        public currentEvent: EventDto;
        public isEditDisabled: boolean;
        public isAddMode: boolean;
        public submitted: boolean;

        public errors: any;
        private validationErrors =
        {
            ///add all server validation codes and related ui field.
            0: { field: "name", message: "validation message." }
        }; 
        
        private serverErrors = {
            validationError: 1
        }

        constructor($scope: ng.IScope, $q: ng.IQService, $location: ng.ILocationService, $routeParams: ng.route.IRouteParamsService,
            notificationFactory: INotificationFactory, staticObjects: IStaticObjects, backendService: EventsService, eventsStatusesService: EventsStatusesService) {

            var ctx = this;

            ctx.$scope = $scope;
            ctx.$q = $q;
            ctx.$location = $location;

            ctx.notificationFactory = notificationFactory;
            ctx.staticObjects = staticObjects;
            ctx.$routeParams = $routeParams;

            ctx.backendService = backendService;
            ctx.eventsStatusesService = eventsStatusesService;

            ctx.isEditDisabled = true;
            ctx.isAddMode = true;
            ctx.asyncSaveOperation = new Sustainalytics.Common.AsyncHttpOperation();
            ctx.asyncLoadOperation = new Sustainalytics.Common.AsyncHttpOperation();


            // load all required data
            ctx.load();

            // scope
            $scope['eventAddEdit'] = ctx;
            $scope.$emit('eventAddEdit.created', ctx);

        }

        private load(): void {
            var ctx = this;

            ctx.isLoading = true;

            var eventId: string = ctx.$routeParams['id'];
            if (eventId) {
                ctx.isAddMode = false;
                ctx.loadEvent(eventId);
                return;
            }
            
            //create new
            var createdEvent = new EventDto();
            createdEvent.status = ctx.eventsStatusesService.statuses.Draft;
            createdEvent.sponsorship = false;
            ctx.currentEvent = createdEvent;

            ctx.isEditDisabled = false;

        }

        private loadEvent(id: string) {
            var ctx = this;
            var def = ctx.$q.defer();

            var getEventPromise: ng.IPromise<EventDto> = ctx.backendService.getEvent(id);

            getEventPromise.then(
                // success
                function (response: EventDto) {
                    console.log(response);
                    ctx.currentEvent = response;
                    ctx.isEditDisabled = (ctx.currentEvent.status != ctx.eventsStatusesService.statuses.Draft);
                },
                // error
                function () {
                    def.reject();
                });

            //ctx.asyncLoadOperation.execute(() => ctx.backendService.getEvent(id)).then(
            //    (response: ng.IHttpPromiseCallbackArg<EventDto>) => {
            //        ctx.currentEvent = response.data;
            //        ctx.isEditDisabled = (ctx.currentEvent.status != ctx.eventsStatusesService.statuses.Draft);
            //    },
            //    (response: ng.IHttpPromiseCallbackArg<IErrorDto>) => {
            //        var message = ctx.staticObjects.getErrorMesageByStatusCode(response.status, response.data);
            //        ctx.notificationFactory.error("Error", message);
            //    });
        }

        public cancel(confirmed:boolean) {
            var ctx = this;

            if (!confirmed) {
                if (!ctx.isEditDisabled && !confirm('Are you sure you want to leave this page?')) {
                    return;
                }
            }
            // notify operation cancelled
            ctx.$location.path('/events');
        }

        public publish() {
            var ctx = this;
            ctx.save(ctx.eventsStatusesService.statuses.Published);//draft
        }

        public saveAsDraft() {
            var ctx = this;
            ctx.save(ctx.eventsStatusesService.statuses.Draft);//draft
        }

        private save(status: number): void {

            this.submitted = true;

            var ctx = this;



            if (ctx.isEditDisabled) {
                ctx.notificationFactory.error('', 'The event cannot be saved in the current state.');
                return;
            }

            var replaceAll = function (find, replace, str) {
                var escapedFind = find.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
                return str.replace(new RegExp(find, 'g'), replace);
            };

           

            if (ctx.currentEvent.body) {
                var newText = $("#eventSummary").text().replace("H1H2H3Toggle HTML", "");
                newText = newText.replace("\n", "");
                newText = newText.trim();

                if (newText.length == 0) {
                    ctx.$scope['form']["body"].$setValidity("required", false);
                }

                //var body = replaceAll("&#10;", "", ctx.currentEvent.body);
                //body = replaceAll("<br/>", "", body).trim();
                //if (!body) {
                //    ctx.$scope['form']["body"].$setValidity("required", false);
                //}
            }

            if (ctx.$scope['form'].$invalid) {
                ctx.notificationFactory.error('', 'Please correct all errors before saving.');
                return;
            }

            if (ctx.currentEvent.startDate > ctx.currentEvent.endDate) {
                ctx.notificationFactory.error('', 'Start Date cannot be greater than End Date');
                return;
            }


            if (ctx.asyncSaveOperation.executing) {
                ctx.notificationFactory.error('Operation in progress.', 'Please wait for previous save operation to complete.');
                return;
            }

           
            var saveOperation = function () {
                if (ctx.isAddMode) {
                    return ctx.backendService.createEvent(ctx.currentEvent);
                }
                else {
                    return ctx.backendService.updateEvent(ctx.currentEvent);
                }
            }

            ctx.currentEvent.status = status;
            ctx.asyncSaveOperation.execute(saveOperation).then(
                (response: ng.IHttpPromiseCallbackArg<any>) => {
                    ctx.currentEvent = response.data;
                    ctx.isEditDisabled = ctx.currentEvent.status !== ctx.eventsStatusesService.statuses.Draft;
                    ctx.isAddMode = false;
                    ctx.notificationFactory.success("Save operation executed successfully.");
                    ctx.cancel(true);
                },
                (response: ng.IHttpPromiseCallbackArg<IErrorDto>) => {
                    if (response && response.data && response.data.errorStatusCode === ctx.serverErrors.validationError) {
                        ctx.notificationFactory.error("Validation failed", "Client and Server version are not incompatible.");
                        return;
                    }

                    var message = ctx.staticObjects.getErrorMesageByStatusCode(response.status, response.data);
                    ctx.notificationFactory.error("Error", message);
                    return;
                });
        }

      
    
    }


    // register controller with News Angular module
    angular.module('Sustainalytics.Events')
        .controller('EventAddEditController', ($scope: ng.IScope, $q: ng.IQService, $location: ng.ILocationService, $routeParams: ng.route.IRouteParamsService,
            notificationFactory: INotificationFactory, staticObjects: IStaticObjects, EventsService, EventsStatusesService) => {
            var ctrl = new EventAddEditController($scope, $q, $location, $routeParams, notificationFactory, staticObjects, EventsService, EventsStatusesService);
            return ctrl;
        });
}